/****************************************************************************

	COPYRIGHT(C) MAXSI SOFTWARE, JONAS 'SORTIE' TERMANSEN 2008, 2009, 2010

    This file is part of Maxsi Compile.

    Maxsi Compile is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Maxsi Compile is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with Maxsi Compile.  If not, see <http://www.gnu.org/licenses/>.

	*/ #include "MaxsiCompileContributors.h" /*

	If you modify this file, please enter your name below and provide contact
	information in MaxsiCompileContributors.h. For more information please see
	MaxsiCompileContributors.h.
	
	Contributors to this file:

	- Jonas 'Sortie' Termansen
	- [your name here]


	MaxsiCompile.exe
	A system to control MaxsiCompile Systems.

	UI.cpp
	The User Interface for MaxsiCompile

****************************************************************************/

#include "MaxsiEngine.h"
#include "UI.h"
#include "Windowsx.h"

MaxsiCompileUIConnection::MaxsiCompileUIConnection()
{
	Tree				=	NULL;
	Form				=	NULL;
	Id					=	0;
	HasProgress			=	false;
	Root.Child			=	NULL;
	Root.Parent			=	NULL;
	Root.Next			=	NULL;
	Root.Prev			=	NULL;
	Root.Name			=	BuildString(1,_MESTR(""));
	Root.Handle			=	TVI_ROOT;
	CurrentlyBrowsed	=	NULL;
}

MaxsiCompileUIConnection::~MaxsiCompileUIConnection()
{
	delete[] Root.Name;
}

MESTR*	MaxsiCompileUIConnection::GetShortName()
{
	MESTR*	Text	=	GetTextText(URLBox);
	MESTR*	Result	=	NULL;

	MESTR*	RXP		=	_MESTR("rxp://");
	MESTR*	FTP		=	_MESTR("ftp://");
	MESTR*	HTTP	=	_MESTR("http://");

	if ( MESTRCMP(Text,_MESTR("")) == 0 )
	{				
		delete[] Text;
		MESTR*	TabId	=	UIToA(Id+1);
				Text	=	BuildString(2,_MESTR("Tab "),TabId);
		delete[] TabId;
		//SendMessage(ProgressBar,PBM_SETMARQUEE,FALSE,0);
		//HasProgress	= false;
	}

	if ( MESTRNICMP(Text,RXP,MESTRLEN(RXP)) == 0 && MESTRLEN(Text) > MESTRLEN(RXP))
	{
		Result		=	BuildString(1,Text+MESTRLEN(RXP));
	}
	else if ( MESTRNICMP(Text,FTP,MESTRLEN(FTP)) == 0 && MESTRLEN(Text) > MESTRLEN(FTP))
	{
		Result		=	BuildString(1,Text+MESTRLEN(FTP));
	}
	else if ( MESTRNICMP(Text,HTTP,MESTRLEN(HTTP)) == 0 && MESTRLEN(Text) > MESTRLEN(HTTP))
	{
		Result		=	BuildString(1,Text+MESTRLEN(HTTP));
	}

	if ( Result )
	{
		delete[] Text;
		return Result;
	}
	else
	{
		return Text;
	}
}

MESTR*	MaxsiCompileUIConnection::GetConnectionURL()
{
	return GetTextText(URLBox);
}

MESTR*	MaxsiCompileUIConnection::GetConnectionName()
{
	MESTR*	MyShortName		=	GetShortName();
	MESTR*	MyURL			=	NULL;
	MESTR*	Result			=	NULL;

	for ( size_t I = 0; I < Form->NumConnections; I++ )
	{
		if ( Form->Connections[I] == NULL ) { continue; }
		if ( Form->Connections[I] == this ) { continue; }

		MESTR*	HisShortName	=	Form->Connections[I]->GetShortName();

		if ( MESTRICMP(MyShortName,HisShortName) == 0 )
		{
			if ( MyURL == NULL ) { MyURL = GetConnectionURL(); }
			MESTR*	HisURL		=	Form->Connections[I]->GetConnectionURL();

			if ( MESTRICMP(MyURL,HisURL) != 0 )
			{
				delete[] HisURL;
				delete[] HisShortName;
				Result			=	GetConnectionURL();
				break;
			}

			delete[] HisURL;
		}

		delete[] HisShortName;
	}

	if ( MyURL ) { delete[] MyURL; }

	if ( Result )
	{
		delete[] MyShortName;
	}
	else
	{
		Result	=	MyShortName;
	}

	return Result;
}
MESTR*	MaxsiCompileUIConnection::GetTabName()
{
	if ( Hidden == false )
	{
		return GetConnectionName();
	}
	else
	{
		MESTR*	ConnectionName	=	GetConnectionName();
		MESTR*	Result			=	BuildString(3,"(",ConnectionName,") (Hidden)");
		delete[] ConnectionName;
		return Result;
	}
}

bool MaxsiCompileUIConnection::CreateControls()
{
	if (!Form) { return false; }

	//Tree			=	CreateTreeView		(Form->WindowHWND,NULL,0,0,0,0);
	Tree			=	CreateListViewM		(Form->WindowHWND);	
	URLBox			=	CreateText			(Form->WindowHWND,NULL,0,0,0,0);
	MESTR*	TabStr	=	GetTabName();		// >MUST< be called after URLBox is created.
	TabButton		=	CreateButton		(Form->WindowHWND,TabStr,0,0,0,0);
	ProgressBar		=	CreateProgressBar	(Form->WindowHWND,NULL,0,0,0,0);
	StatusLabel		=	CreateLabel			(Form->WindowHWND,_MESTR("Connecting..."),0,0,0,0);
	CloseTab		=	CreateButton		(Form->WindowHWND,_MESTR("X"),0,0,0,0);
	Left			=	CreateButton		(Form->WindowHWND,_MESTR("<"),0,0,0,0);
	Right			=	CreateButton		(Form->WindowHWND,_MESTR(">"),0,0,0,0);
	Connect			=	CreateButton		(Form->WindowHWND,_MESTR("Connect"),0,0,0,0);
	delete[] TabStr;

	AddListViewColumn(Tree,0,_MESTR("Name"),150);
	AddListViewColumn(Tree,1,_MESTR("Size"),50);
	AddListViewColumn(Tree,2,_MESTR("Type"),100);

	return true;
}

bool MaxsiCompileUIConnection::DeleteControls()
{
	if ( Tree ) { DestroyWindow(Tree); Tree = NULL; }
	if ( URLBox ) { DestroyWindow(URLBox); Tree = NULL; }
	if ( TabButton ) { DestroyWindow(TabButton); TabButton = NULL; }
	if ( ProgressBar ) { DestroyWindow(ProgressBar); ProgressBar = NULL; }
	if ( StatusLabel ) { DestroyWindow(StatusLabel); StatusLabel = NULL; }
	if ( CloseTab ) { DestroyWindow(CloseTab); CloseTab = NULL; }
	if ( Left ) { DestroyWindow(Left); Left = NULL; }
	if ( Right ) { DestroyWindow(Right); Right = NULL; }
	if ( Connect ) { DestroyWindow(Connect); Connect = NULL; }

	return true;
}

bool MaxsiCompileUIConnection::BrowseResource(MaxsiCompileUIResource* Resource)
{
	if ( Resource == NULL ) { return false; }
	if ( Resource == CurrentlyBrowsed ) { return true; }
	if ( CurrentlyBrowsed && UnBrowseResource() == false ) { return false; }

	// First make the ..
	
	if ( Resource->Parent )
	{
		LVITEMW	Item;

		Item.mask		=	LVIF_TEXT | LVIF_PARAM | LVIF_STATE; 
		Item.state		=	0; 
		Item.stateMask	=	0;
		Item.iItem		=	0;
		Item.iImage		=	0;
		Item.iSubItem	=	0;
		Item.lParam		=	(LPARAM)NULL;
		Item.pszText	=	LPSTR_TEXTCALLBACK; // sends an LVN_GETDISP message.
		ListView_InsertItem(Tree, &Item);
	}

	if ( Resource->Child )
	{
		MaxsiCompileUIResource*		Temp	=	Resource->Child;

		LVITEMW	Item;
		Item.iItem			=	-1;

		if ( Resource->Parent ) { Item.iItem++; }

		while ( Temp )
		{
			Item.mask		=	LVIF_TEXT | LVIF_PARAM | LVIF_STATE; 
			Item.state		=	0; 
			Item.stateMask	=	0;
			Item.iItem++;
			Item.iImage		=	0;
			Item.iSubItem	=	0;
			Item.lParam		=	(LPARAM)Temp;
			Item.pszText	=	LPSTR_TEXTCALLBACK; // sends an LVN_GETDISP message.
			ListView_InsertItem(Tree, &Item);

			Temp->IsShown	=	true;
			Temp->ListId	=	Item.iItem;
			Temp			=	Temp->Next;
		}
	}

	CurrentlyBrowsed		=	Resource;

	return true;
}

bool MaxsiCompileUIConnection::UnBrowseResource()
{
	if ( CurrentlyBrowsed )
	{
		for ( MaxsiCompileUIResource* Temp = CurrentlyBrowsed->Child; Temp; Temp = Temp->Next )
		{
			if ( Temp->IsShown )
			{
				Temp->IsShown	=	false;
			}
		}
	}

	ListView_DeleteAllItems(Tree);

	return true;
}

bool MaxsiCompileUIConnection::AddResource(MESTR* ResourceName)
{
	size_t		Dirs		=	0; 
	size_t		Temp		=	0;
	MESTR*		Temp2		=	ResourceName;

	// Quickly calculate how many directories are in ResourceName.
	while (true) { Temp = MESTRLEN(Temp2); if ( Temp == 0 )	{ break; } Temp	= FindChar(Temp2,'/' ,MESTRLEN(Temp2)); if ( Temp == -1 ) {	break; } Dirs++; Temp2 += Temp+1; } Temp2	=	ResourceName;
	while (true) { Temp = MESTRLEN(Temp2); if ( Temp == 0 )	{ break; } Temp	= FindChar(Temp2,'\\',MESTRLEN(Temp2)); if ( Temp == -1 ) {	break; } Dirs++; Temp2 += Temp+1; } Temp2	=	ResourceName;

	// Create a quick-lookup table!
	MESTR**		LookUp		=	new MESTR*[Dirs+1];
	MESTR*		LookUpStr	=	BuildString(1,ResourceName);
	size_t		LookUpSize	=	MESTRLEN(LookUpStr);
	size_t		LookUpTemp	=	0;
	MESTR*		LookUpTemp2	=	LookUpStr;

	// Parse LookUpStr and make it a lookup table in LookUp!
	for ( size_t I = 0; I < LookUpSize; I++ )
	{
		if ( LookUpStr[I] == '/' || LookUpStr[I] == '\\' )
		{
			LookUpStr[I]			=	0;
			LookUp[LookUpTemp]		=	LookUpTemp2;
			LookUpTemp2				=	LookUpStr+I+1;
			LookUpTemp++;
		}
	}
	LookUp[Dirs]					=	LookUpTemp2;

	MaxsiCompileUIResource*	Resource	=	&Root;

	// Create all the resources required!
	for ( size_t I = 0; I <= Dirs && Resource; I++ )
	{
		Resource	=	EnsureResourceExists(LookUp[I],Resource);
	}

	// Now that we have created our resource, clean up!

	delete[] LookUpStr;
	delete[] LookUp;

	if ( Resource && Resource != &Root )
	{
		return true;
	}
	else
	{
		return false;
	}
}

MaxsiCompileUIResource* MaxsiCompileUIConnection::EnsureResourceExists(MESTR* ResourceName, MaxsiCompileUIResource* Parent)
{
	MaxsiCompileUIResource*		NewGuy	=	NULL;

	// If the parent has no childs, then the folder won't exist, so let's just create it.
	if ( Parent->Child == NULL )
	{
		NewGuy				=	new MaxsiCompileUIResource;
		NewGuy->Name		=	BuildString(1,ResourceName);
		NewGuy->Parent		=	Parent;
		NewGuy->Next		=	NULL;
		NewGuy->Prev		=	NULL;
		NewGuy->Child		=	NULL;
		Parent->Child		=	NewGuy;
	}
	else
	{
		MaxsiCompileUIResource*		Temp;
		MaxsiCompileUIResource*		Last;

		for ( Temp = Parent->Child; Temp; Temp = Temp->Next )
		{
			int	Relationship	=	MESTRICMP(ResourceName,Temp->Name);

			Last				=	Temp;

			// Is ResourceName more than Temp->Name? If so, then keep trying.
			if ( Relationship > 0 ) { continue; } // Nope! Go to the next entry!

			// Is ResourceName less than Temp->Name? If so, add ResourceName before Temp
			if ( Relationship < 0 ) { break; } // We order our list of entries in the table alphabetically.

			return Temp; // Sounds like this is our guy! (Relationship==0)
		}
		
		NewGuy				=	new MaxsiCompileUIResource;

		NewGuy->Child		=	NULL;
		NewGuy->Name		=	BuildString(1,ResourceName);
		NewGuy->Parent		=	Parent;

		if ( Temp == NULL )
		{
			// If Temp == NULL, then FolderName is greater than the Last->Name. So let's put it after.
			NewGuy->Next	=	NULL;
			NewGuy->Prev	=	Last;
			Last->Next		=	NewGuy;
		}
		else
		{
			// If Temp != NULL, then FolderName is less than Temp->Name. So let's put it before.
			NewGuy->Next	=	Temp;
			NewGuy->Prev	=	Temp->Prev;
			Temp->Prev		=	NewGuy;
			if ( NewGuy->Prev ) { NewGuy->Prev->Next = NewGuy; }
			if ( Parent->Child == Last ) { Parent->Child = NewGuy; }
		}
	}

	//TVINSERTSTRUCTW	Insert;

	//Insert.hParent			=	Parent->Handle;

	//if ( NewGuy->Prev == NULL )
	//{
	//	Insert.hInsertAfter	=	TVI_FIRST;
	//}
	//else
	//{
	//	Insert.hInsertAfter	=	NewGuy->Prev->Handle;
	//}

	//
	//Insert.item.mask		=	TVIF_TEXT /*| TVIF_IMAGE | TVIF_SELECTEDIMAGE*/ | TVIF_PARAM; 
	//Insert.item.pszText		=	MESTRWP(NewGuy->Name);
	//Insert.item.cchTextMax	=	MESTRLEN(NewGuy->Name)+1;
	//Insert.item.cChildren	=	0;
	//Insert.item.lParam		=	0;

	//NewGuy->Handle	=	(HTREEITEM)SendMessageW(Tree,TVM_INSERTITEM,0,(LPARAM)&Insert);

	//MESTRUWP(Insert.item.pszText);

	return NewGuy;
}

bool MaxsiCompileUIConnection::ResizeControls(WORD Width, WORD Height)
{
	MoveWindow(TabButton,(Width-100)*Id/Form->NumConnections,0,(Width-100)/Form->NumConnections,24,TRUE);
	
	if ( Hidden == false )
	{
		WORD	ALeft	=	(Width-10)*Order/Form->NumShownConnections+5;
		WORD	AWidth	=	(Width-10)/Form->NumShownConnections;
		WORD	ARight	=	ALeft+AWidth;
		WORD	ATop	=	24;
		WORD	AHeight	=	Height;
		WORD	ABottom	=	ATop+AHeight;

		WORD	ULeft	=	ALeft+2;
		WORD	UWidth	=	AWidth-4;
		WORD	URight	=	ULeft+UWidth;
		WORD	UTop	=	ATop+10;
		WORD	UHeight	=	24;
		WORD	UBottom	=	UTop+UHeight;

		WORD	XLeft	=	ALeft+2;
		WORD	XWidth	=	24;
		WORD	XRight	=	XLeft+XWidth;
		WORD	XTop	=	UBottom+1;
		WORD	XHeight	=	24;
		WORD	XBottom	=	XTop+XHeight;

		WORD	MLLeft	=	XRight+5;
		WORD	MLWidth	=	24;
		WORD	MLRight	=	MLLeft+MLWidth;
		WORD	MLTop	=	UBottom+1;
		WORD	MLHeight=	24;
		WORD	MLBottom=	MLTop+MLHeight;

		WORD	MRLeft	=	MLRight;
		WORD	MRWidth	=	24;
		WORD	MRRight	=	MRLeft+MRWidth;
		WORD	MRTop	=	UBottom+1;
		WORD	MRHeight=	24;
		WORD	MRBottom=	MRTop+MRHeight;

		WORD	CLeft	=	MRRight+5;
		WORD	CWidth	=	URight-CLeft; if ( CLeft > URight ) { CWidth = 1; }
		WORD	CRight	=	CLeft+CWidth;
		WORD	CTop	=	UBottom+1;
		WORD	CHeight	=	24;
		WORD	CBottom	=	CTop+CHeight;

		WORD	PLeft	=	ALeft+2;
		WORD	PWidth	=	AWidth-4;
		WORD	PRight	=	PLeft+PWidth;
		WORD	PTop	=	ABottom-34;
		WORD	PHeight	=	0;
		WORD	PBottom	=	PTop+PHeight;

		if ( HasProgress )
		{
			PTop		=	ABottom-80;
			PHeight		=	20;
			PBottom		=	PTop+PHeight;
		}

		WORD	LLeft	=	ALeft+2;
		WORD	LWidth	=	AWidth-4;
		WORD	LRight	=	LLeft+LWidth;
		WORD	LTop	=	PBottom+1;
		WORD	LHeight	=	24;
		WORD	LBottom	=	LTop+LHeight;

		WORD	TLeft	=	ALeft+2;
		WORD	TWidth	=	AWidth-4;
		WORD	TRight	=	TLeft+TWidth;
		WORD	TTop	=	10+CBottom;
		WORD	THeight	=	PTop-TTop;
		WORD	TBottom	=	TTop+THeight;

		ShowWindow(URLBox,SW_SHOW);
		ShowWindow(Tree,SW_SHOW);
		ShowWindow(CloseTab,SW_SHOW);
		ShowWindow(Left,SW_SHOW);
		ShowWindow(Right,SW_SHOW);
		ShowWindow(Connect,SW_SHOW);
		if ( HasProgress ) { ShowWindow(ProgressBar,SW_SHOW); } else { ShowWindow(ProgressBar,SW_HIDE); }
		if ( HasProgress ) { ShowWindow(StatusLabel,SW_SHOW); } else { ShowWindow(StatusLabel,SW_HIDE); }

		MoveWindow(URLBox,ULeft,UTop,UWidth,UHeight,TRUE);
		MoveWindow(Tree,TLeft,TTop,TWidth,THeight,TRUE);
		MoveWindow(ProgressBar,PLeft,PTop,PWidth,PHeight,TRUE);
		MoveWindow(StatusLabel,LLeft,LTop,LWidth,LHeight,TRUE);
		MoveWindow(CloseTab,XLeft,XTop,XWidth,XHeight,TRUE);
		MoveWindow(Left,MLLeft,MLTop,MLWidth,MLHeight,TRUE);
		MoveWindow(Right,MRLeft,MRTop,MRWidth,MRHeight,TRUE);
		MoveWindow(Connect,CLeft,CTop,CWidth,CHeight,TRUE);
	}
	else
	{
		ShowWindow(URLBox,SW_HIDE);
		ShowWindow(Tree,SW_HIDE);
		ShowWindow(CloseTab,SW_HIDE);
		ShowWindow(Left,SW_HIDE);
		ShowWindow(Right,SW_HIDE);
		ShowWindow(Connect,SW_HIDE);
		ShowWindow(ProgressBar,SW_HIDE);
		ShowWindow(StatusLabel,SW_HIDE);
	}

	return true;
}

LRESULT APIENTRY MaxsiCompileUIConnection::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	LPNMHDR		NotificationFilter	=	(LPNMHDR)lParam;

	if ( message == WM_COMMAND )
	{
		HWND Subject = (HWND)lParam;

		if ( Subject == TabButton )
		{
			Hidden = !Hidden;
			
			if ( Hidden == true )
			{
				--Form->NumShownConnections;

				for ( size_t I = 0; I < Form->NumConnections; I++ )
				{
					if ( Form->Connections[I]->Order > Order )
					{
						--Form->Connections[I]->Order;
					}
				}
			}
			else
			{
				for ( size_t I = 0; I < Form->NumConnections; I++ )
				{
					if ( Form->Connections[I]->Order >= Order && Form->Connections[I] != this)
					{
						++Form->Connections[I]->Order;
					}
				}
				++Form->NumShownConnections;
			}
		}
		else if ( Subject == URLBox )
		{
			// The url will be updated.
		}
		else if ( Subject == CloseTab )
		{
			Form->DestroyTab(Id); // Beware, we are actually deleting ourself.
		}
		else if ( Subject == Left )
		{
			if ( Order != 0 )
			{
				for ( size_t I = 0; I < Form->NumConnections; I++ )
				{
					if ( Form->Connections[I]->Order == Order-1 )
					{
						++Form->Connections[I]->Order;
					}
				}
				Order--;
			}
		}
		else if ( Subject == Right )
		{
			if ( Order != (Form->NumShownConnections-1) )
			{
				for ( size_t I = 0; I < Form->NumConnections; I++ )
				{
					if ( Form->Connections[I]->Order == Order+1 )
					{
						--Form->Connections[I]->Order;
					}
				}
				Order++;
			}
		}
		else if ( Subject == Connect )
		{
			AddResource(_MESTR("index.php"));
			AddResource(_MESTR("copying.txt"));
			AddResource(_MESTR("hacking.txt"));
			AddResource(_MESTR("readme.txt"));
			AddResource(_MESTR("distribution"));
			AddResource(_MESTR("distribution/index.php"));
			AddResource(_MESTR("distribution/addons/achievements/addon.php"));
			AddResource(_MESTR("distribution/addons/contentserver/addon.php"));
			AddResource(_MESTR("distribution/addons/masterserver/addon.php"));
			AddResource(_MESTR("distribution/addons/shared/addon.php"));
			AddResource(_MESTR("distribution/addons/shared/init.php"));

			BrowseResource(&Root);
		}
	}
	else if ( message == WM_NOTIFY &&
			NotificationFilter->hwndFrom == Tree &&
			(NotificationFilter->code == LVN_GETDISPINFOW ||
			NotificationFilter->code == LVN_GETDISPINFOA) )
	{
		NMLVDISPINFOM* plvdi			=	(NMLVDISPINFOM*)lParam;    
		
		if ( plvdi->item.iItem == 0 && plvdi->item.lParam == 0 )
		{
			if ( plvdi->item.iSubItem == 0 )
			{
				plvdi->item.pszText = _MESTR("../ (Top Folder)");
			}
		}
		else
		{
			MaxsiCompileUIResource*	Resource	=	(MaxsiCompileUIResource*)plvdi->item.lParam;
			switch (plvdi->item.iSubItem)
			{
				case 0:
				plvdi->item.pszText = Resource->Name;
				break;

				case 1:
				plvdi->item.pszText = _MESTR("N/A");
				break;

				case 2:
				if ( Resource->Child )
				{
					plvdi->item.pszText = _MESTR("Folder");
				}
				else
				{
					plvdi->item.pszText = _MESTR("Resource");
				}
				break;

				default:
				break;
			}
		}

		return 0;
	}
	else if ( message == WM_NOTIFY &&
			NotificationFilter->hwndFrom == Tree &&
			NotificationFilter->code == LVN_ITEMACTIVATE  )
	{
		UINT	Num						=	SendMessage(Tree,LVM_GETNEXTITEM,-1,LVNI_SELECTED);

		MaxsiCompileUIResource*	Resource	=	CurrentlyBrowsed->Child;

		while ( Resource )
		{
			if ( Resource->ListId == (int)Num ) { break; }
			Resource	=	Resource->Next;
		}

		if ( Resource ) 
		{
			BrowseResource(Resource);
		}
		else if ( CurrentlyBrowsed->Parent )
		{
			BrowseResource(CurrentlyBrowsed->Parent);
		}
	}

    return (0);
}

bool MaxsiCompileUI::InitializeForm(ME_Window* Parent)
{
	BaseClass::InitializeForm(Parent);

	NumConnections		=	1;
	NumShownConnections	=	NumConnections;
	Connections			=	new MaxsiCompileUIConnection*[NumConnections];

	memset(Connections,0,sizeof(MaxsiCompileUIConnection*)*NumConnections);

	for ( size_t I = 0; I < NumConnections; I++ )
	{
		Connections[I]			=	new MaxsiCompileUIConnection;
		Connections[I]->Form	=	this;
		Connections[I]->Id		=	I;
		Connections[I]->Order	=	I;
		Connections[I]->Hidden	=	false;
		Connections[I]->CreateControls();
	}

	NewTab	=	CreateButton(WindowHWND,_MESTR("New Tab"),0,0,0,0);

	Initialized	=	true;

	RECT ClientSpace;
	GetClientRect (WindowHWND, &ClientSpace);
	
	NewResolution((WORD)ClientSpace.right,(WORD)ClientSpace.bottom);

	return true;
}

bool MaxsiCompileUI::CreateTab()
{
	MaxsiCompileUIConnection**	NewConnections			=	new MaxsiCompileUIConnection*[NumConnections+1];

	for ( size_t I = 0; I < NumConnections; I++ )
	{
		NewConnections[I]	=	Connections[I];
	}

	MaxsiCompileUIConnection*	Connection			=	new MaxsiCompileUIConnection;
	NewConnections[NumConnections]	=	Connection;
	Connection->Form	=	this;
	Connection->Id		=	NumConnections;
	Connection->Order	=	NumShownConnections;
	Connection->Hidden	=	false;
	NumShownConnections++;
	NumConnections++;
	
	delete[]	Connections;
	Connections			=	NewConnections;

	Connection->CreateControls();

	
	return true;
}

bool MaxsiCompileUI::DestroyTab(size_t PoorBastard)
{
	MaxsiCompileUIConnection**	NewConnections			=	new MaxsiCompileUIConnection*[NumConnections-1];

	for ( size_t I = 0; I < PoorBastard; I++ )
	{
		NewConnections[I]	=	Connections[I];
	}
	for ( size_t I = PoorBastard+1; I < NumConnections; I++ )
	{
		NewConnections[I-1]	=	Connections[I];
	}

	--NumShownConnections;

	for ( size_t I = 0; I < NumConnections; I++ )
	{
		if ( Connections[I]->Order > Connections[PoorBastard]->Order && I != PoorBastard)
		{
			--Connections[I]->Order;
		}
		if ( Connections[I]->Id > Connections[PoorBastard]->Id && I != PoorBastard)
		{
			--Connections[I]->Id;
		}
	}

	Connections[PoorBastard]->DeleteControls();
	delete		Connections[PoorBastard];
	delete[]	Connections;
	
	--NumConnections;
	
	Connections			=	NewConnections;


	for ( size_t I = 0; I < NumConnections; I++ )
	{
		MESTR*	TabName	=	Connections[I]->GetTabName();

		SetWindowTextM(Connections[I]->TabButton,TabName);

		delete[] TabName;
	}

	return true;
}



bool MaxsiCompileUI::TerminateForm( void )
{
	if (!Initialized) { return false; }

	if ( Connections )
	{
		for ( size_t I = 0; I < NumConnections; I++ )
		{
			if ( Connections[I] )
			{
				Connections[I]->DeleteControls();
				delete Connections[I];
			}
		}

		delete[] Connections;
	}

	DestroyWindow(NewTab);

	return	BaseClass::TerminateForm();
}


bool MaxsiCompileUI::RenderForm( HWND hWnd )
{	
	if (!Initialized) { return false; }
    PAINTSTRUCT ps          = {0};
	HDC hDC = BeginPaint (hWnd, &ps);

	RECT rectClient;

    GetClientRect (hWnd, &rectClient);
	
	EndPaint (hWnd, &ps);

	return true;
}

LRESULT APIENTRY MaxsiCompileUI::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	if (!Initialized) { return 0; }

	if ( message == WM_COMMAND )
	{
			
		if ( LOWORD(wParam) == BN_CLICKED && NewTab == (HWND)lParam)
		{
			CreateTab();

			RECT ClientSpace;
			GetClientRect (WindowHWND, &ClientSpace);
			
			NewResolution((WORD)ClientSpace.right,(WORD)ClientSpace.bottom);
		}
		else// if ( LOWORD(wParam) == BN_CLICKED || LOWORD(wParam) == EN_UPDATE )
		{
			if ( Connections )
			{
				for ( size_t I = 0; I < NumConnections; I++ )
				{
					if ( Connections[I] )
					{
						Connections[I]->WindowProc(hWnd,message,wParam,lParam);
					}
				}

				for ( size_t I = 0; I < NumConnections; I++ )
				{
					if ( Connections[I] )
					{
						MESTR*	TabName	=	Connections[I]->GetTabName();

						SetWindowTextM(Connections[I]->TabButton,TabName);

						delete[] TabName;
					}
				}
			}

			

			RECT ClientSpace;
			GetClientRect (WindowHWND, &ClientSpace);
			
			NewResolution((WORD)ClientSpace.right,(WORD)ClientSpace.bottom);

		}
	}
	else if ( message == WM_NOTIFY )
	{
		// (message == WM_NOTIFY && ((LPNMHDR)lParam)->code == LVN_GETDISPINFO)
		if ( Connections )
		{
			for ( size_t I = 0; I < NumConnections; I++ )
			{
				if ( Connections[I] )
				{
					Connections[I]->WindowProc(hWnd,message,wParam,lParam);
				}
			}
		}
		return BaseClass::WindowProc(hWnd,message,wParam,lParam);
	}
	else
	{
		return BaseClass::WindowProc(hWnd,message,wParam,lParam);
	}
    return (0);
}


bool MaxsiCompileUI::NewResolution( WORD Width, WORD Height)
{	
	RECT r;
	r.bottom=Height;
	r.top=0;
	r.left=0;
	r.right=Width;
	//RedrawWindow(WindowHWND,&r,0, RDW_INVALIDATE | RDW_NOINTERNALPAINT | RDW_NOCHILDREN | RDW_ERASE);

	if ( Connections )
	{
		for ( size_t I = 0; I < NumConnections; I++ )
		{
			if ( Connections[I] )
			{
				Connections[I]->ResizeControls(Width, Height);
			}
		}
	}

	MoveWindow(NewTab,Width-100,0,100,24,TRUE);

	return true;
}